Skip to content

Git 常用命令速查 ​

按功能分类整理 Git 常用命令,覆盖日常开发的配置、提交、分支、远程协作与标签操作;先以「三棵树」工作模型说明工作区、暂存区与提交的关系,随后讲清 git pull、git fetch、git merge 与 git rebase 四个命令的关系与分工,再补充三组常用操作:回滚本地与远程分支、修改已推送的提交信息、git stash 暂存中断现场,末尾处理本地 tag 与远程不一致导致同步被拒的问题。适合放在手边随查随用。

命令速查表 ​

类别 命令 说明
配置 git config --global user.name "Your Name" 设置全局用户名
git config --global user.email "email@example.com" 设置全局邮箱
git config --list 查看当前配置
初始化 git init 初始化一个新的 Git 仓库
git clone <url> 克隆远程仓库到本地
查看状态 git status 查看工作区状态(哪些文件被修改、暂存等)
添加与提交 git add <file> 将指定文件添加到暂存区
git add . 添加当前目录所有更改到暂存区
git commit -m "commit message" 提交暂存区内容到本地仓库,并附带提交信息
查看历史 git log 查看提交历史(详细)
git log --oneline 以单行形式显示提交历史
git log --graph --all --oneline 图形化显示所有分支的提交历史
差异比较 git diff 查看工作区与暂存区之间的差异
git diff --staged 或 git diff --cached 查看暂存区与最新提交之间的差异(两者等价)
撤销操作 git checkout -- <file> 丢弃工作区对文件的修改(恢复到最近一次暂存/提交状态)
git reset HEAD <file> 从暂存区移除文件(保留工作区修改)
git reset --hard HEAD~1 回退到上一个提交(会丢失最近一次提交的所有更改),慎用
git revert <commit> 生成一笔反向提交,撤销指定提交的改动(不改写历史)
分支管理 git branch 列出本地所有分支
git branch <branch-name> 创建新分支
git checkout <branch-name> 切换到指定分支
git switch <branch-name> (Git 2.23+)切换分支(推荐替代 checkout)
git checkout -b <branch-name> 创建并切换新分支
git branch -d <branch-name> 删除已合并的分支
git branch -D <branch-name> 强制删除分支(即使未合并)
git merge <branch-name> 合并指定分支到当前分支
远程操作 git remote -v 查看远程仓库地址
git remote add origin <url> 添加远程仓库(通常命名为 origin)
git push -u origin <branch> 首次推送本地分支到远程,并设置上游跟踪
git push 推送当前分支到关联的远程分支
git pull 拉取远程更新并合并(默认相当于 fetch + merge)
git fetch 获取远程更新但不合并
标签管理 git tag 列出所有标签
git tag <tagname> 创建轻量标签
git tag -a <tagname> -m "message" 创建带注释的标签
git push origin <tagname> 推送指定标签到远程
git push origin --tags 推送所有标签到远程
其他实用命令 git stash 临时保存当前工作区和暂存区的修改
git stash pop 恢复最近一次 stash 的内容
git reflog 查看 HEAD 变更记录(可用于找回「丢失」的提交)
git show <commit-id> 显示某次提交的详细信息

工作模型:三棵树 ​

本地仓库由 Git 维护的三棵树组成:工作目录(工作区)、暂存区(Index/stage,保存待提交的临时改动)、HEAD(指向最近一次提交的结果)。

日常操作就是在这几棵树之间搬动改动:git status 查看文件状态(已修改未暂存、已暂存未提交),git add 把工作区改动放进暂存区,git commit 把暂存区内容提交到 HEAD 并清空暂存区,git push 把本地提交送到远端。理解这个模型后,后面 pull/fetch/merge 的行为与 git diff 各变体的含义都有了落点:

bash
git diff                                   # 工作区 vs 暂存区
git diff --cached                          # 暂存区 vs HEAD(add 之后仍能看)
git diff <source_branch> <target_branch>   # 两个分支之间

git add 之后 git diff 无输出并不是差异丢失——默认的 diff 只比较工作区与暂存区,add 后两者一致自然没有输出,要看已暂存的改动用 git diff --cached(与 --staged 等价)。

pull、fetch、merge 与 rebase 的关系 ​

git fetch 与 git pull 都用于更新本地代码,区别在于是否合并:

  • git fetch 只获取远端仓库的分支数据,更新本地的远程跟踪分支(如 origin/master),不进行合并,工作区不受影响
  • git pull 在 fetch 的基础上更进一步。官方文档的描述:把远端仓库的变更合入当前分支——当前分支落后于远端时,默认 fast-forward(快进)到远端;两者发生分歧时,需要通过 --rebase 或 --no-rebase(或 pull.rebase 配置)指定调和方式

更准确地说,git pull 先执行 git fetch,然后根据配置或命令行参数调用 git merge 或 git rebase 完成分支调和,默认是 merge。

merge 与 rebase 处理分歧的结果不同。假设当前分支与远端出现如下分歧:

text
     A---B---C master on origin
    /
D---E---F---G feature
    ^     origin/master in your repository

git pull(merge 方式)会把远端新提交(A、B、C)合并到当前分支,创建一个新的合并提交 H:

text
      A---B---C origin/master
     /         \
D---E---F---G---H  feature

rebase 则把当前分支上不在上游(<upstream>)中的提交(F、G)暂存到临时区域,将分支重置到上游最新提交,再把这些提交逐个重放到顶部。上游提交 C 不会被改写,被改写的是自己的 F、G(变成 F'、G'):

text
      A---B---C---F'--G' feature
     /
D---E
    ^  origin/master in your repository

merge 保留真实的分叉历史,rebase 产出线性的历史记录。整理已有提交历史的更多操作(交互式 rebase、cherry-pick)见 Git Rebase 与 Cherry-pick 实用指南。

修改已推送的 commit 信息 ​

场景:最近一次 commit 已经推送到远端,发现提交信息写错了,想改过来。前提是本地处于该分支最新状态。

  1. git commit --amend 进入编辑器(默认 vim):按 i 进入编辑模式修改提交信息,编辑完按 Esc,输入 :wq 保存退出
  2. git push -f 强制推送,覆盖远端

编辑器不一定是 vim,能保存即可,例如 nano:Ctrl+O 保存,Ctrl+X 退出。

force push 会改写远端历史:该 commit 已被他人拉取时,会给他们制造冲突,共享分支上慎用。更稳妥的写法是 git push --force-with-lease——远端在本地不知情时被更新过,推送会被拒绝,降低覆盖他人提交的风险。

回滚:本地与远程分支 ​

本地回滚用 git reset:

bash
git reset --hard <commit-id>   # 回滚到 commit-id,其后的提交全部去除
git reset --hard HEAD~3        # 回滚最近 3 次提交

远程回滚的典型场景:自动部署系统发布后发现问题,需要把分支退回某个 commit 再重新发布。原理是先把本地分支退回去,再让远程分支重新指向旧提交,操作前务必备份。两种方法效果等价,方法二更直接:

bash
# 方法一:删远程分支重建
git checkout your_branch
git pull
git branch your_branch_backup        # 备份当前分支
git reset --hard <the_commit_id>     # 回退到指定的 commit_id
git push origin :your_branch         # 删除远程分支(等价写法 --delete)
git push origin your_branch          # 用回滚后的本地分支重建远程分支
git push origin :your_branch_backup  # 确认成功后删除备份分支

# 方法二:强制推送
git checkout your_branch
git pull
git branch your_branch_backup
git reset --hard <the_commit_id>
git push -f origin your_branch       # 强制覆盖远程分支

git push -f 会绕过远端保护,若服务端开启了分支保护,需要先解除保护或改用 git revert 生成反向提交。分支已被他人拉取时,优先用 git revert,避免强推改写公共历史。

git stash:暂存中断现场 ​

开发中途要切去处理别的问题,手头改动不适合带着半成品提交时,用 git stash 把当前工作区和暂存区的修改整体存起来,稍后恢复。

git stash 默认忽略未跟踪和被 ignore 的文件;stash 记录只存在本地,不会随 git push 上传。

bash
git stash push -m "message"    # 暂存并附说明(推荐)
git stash list                 # 查看暂存栈

git stash save "message" 是旧写法,Git 2.16 起已弃用;push 还支持指定路径,只暂存部分文件。

处理未跟踪与被忽略的文件:

  • git stash -u / git stash --include-untracked:连未跟踪文件一起暂存
  • git stash -a / git stash --all:连被 ignore 的文件也一起暂存

恢复与清理:

bash
git stash apply stash@{x}   # 释放编号 x 的暂存,记录保留在 list 中
git stash pop               # 释放最近一次暂存,并从 list 中删除该记录
git stash drop stash@{1}    # 删除指定暂存
git stash clear             # 清空暂存栈

apply 与 pop 的区别只在是否出栈:需要把同一次暂存恢复到多个分支时用 apply。

本地 tag 与远程不一致导致同步被拒 ​

场景:git pull / git fetch 时报错,同步中断:

text
 ! [rejected] v3.38.0 -> v3.38.0  (would clobber existing tag)

本地存在与远程同名的 tag,但两者指向不同的提交。常见原因是本地重新打过这个 tag(如 git tag -f),或者远程 tag 被人删掉重建过。Git 出于安全考虑拒绝覆盖本地 tag。

处理思路是删掉不一致的本地 tag,再从远程重新拉取:

  1. 查看远程 tag:
bash
git ls-remote -t <remote>
  1. 查看本地 tag:
bash
git tag -l
  1. 删除与远程不一致的本地 tag:
bash
git tag -d v3.38.0
  1. 重新拉取远程 tag 并同步代码:
bash
git fetch origin
git pull

关于 --prune-tags:git fetch origin --prune-tags 会按 refs/tags/*:refs/tags/* 强制拉取远程全部 tag,但单独使用时并不会清理本地多余的 tag——官方文档写明,清理仅在 --prune 同时启用时生效。要一步清掉本地已不在远程的 tag,用:

bash
git fetch origin --prune --prune-tags

也可以写进配置长期生效:

bash
git config fetch.prune true
git config fetch.pruneTags true

要点 ​

  • 查任意命令的权威说明用 git help <command>
  • --hard 与 force push 都是破坏性操作,执行前确认自己清楚后果
  • Git 2.23 起分支操作推荐用 git switch、撤销暂存推荐用 git restore --staged,职责比 git checkout 清晰
最近更新

基于 VitePress 构建